package voxietest1;

//To set up environment to compile:
	//   set path="c:\Program Files\Java\jdk1.6.0_24\bin";%path%
	//   set classpath="c:\Program Files\Java\jdk1.6.0_24\lib"
	//
	//To compile: (.java to .class)
	//   javac -cp jna.jar voxiesimp.java
	//
	//To run, make sure 64-bit VOXILIB.DLL is in same directory, and run:
	//   java -cp .;jna.jar voxiesimp

import com.sun.jna.Library;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.Native;

public class voxiesimp
{
	public static class point2d extends com.sun.jna.Structure
	{
		public point2d() { setAlignType(Structure.ALIGN_NONE); }
		public point2d(float xx, float yy) { setAlignType(Structure.ALIGN_NONE); x = xx; y = yy; }
		public float x, y;
	}
	public static class voxi_wind_t extends Structure
	{
		public voxi_wind_t() { setAlignType(Structure.ALIGN_NONE); }
		public double freq; //initial freq set once at beginning
		public double phase, emuhang, emuvang, emudist; //can be modified later
		public point2d proj0, proj1, proj2, proj3, proj4, proj5, proj6, proj7;
		public float aspx, aspy, aspz;
		public int useemu, hidewind, voxie_vid, voxie_aud, sndfx_aud0, sndfx_aud1, projrate, framepervol, samprate, nchans;
		public int usecol, drawboth, move, xdim, ydim, x0, y0, x1, y1, emurendmode, useprojcomp; //can be modified later
	}
	public static class voxi_frame_t extends Structure
	{
		public voxi_frame_t() { setAlignType(Structure.ALIGN_NONE); }
		public long f, p, fp;
		public int x, y, usecol, drawplanes, x0, y0, x1, y1;
		public float xmul, ymul, zmul, xadd, yadd, zadd;
	}
	public static class point3d extends Structure
	{
		public point3d() { setAlignType(Structure.ALIGN_NONE); }
		public point3d(float xx, float yy, float zz) { setAlignType(Structure.ALIGN_NONE); x = xx; y = yy; z = zz; }
		public float x, y, z;
	}
	public static class pol_t extends Structure
	{
		public pol_t() { setAlignType(Structure.ALIGN_NONE); }
		public void set(float xx, float yy, float zz, int pp2) { x = xx; y = yy; z = zz; p2 = pp2; }
		public float x, y, z;
		public int p2;
	}
	public static class tiletype extends Structure
	{
		public tiletype() { setAlignType(Structure.ALIGN_NONE); }
		public long f, p, x, y;
	}
	public static class voxi_inputs_t extends Structure
	{
		public voxi_inputs_t() { setAlignType(Structure.ALIGN_NONE); }
		public int bstat, obstat, dmousx, dmousy, dmousz;
	}

	private static Voxilib voxilib = (Voxilib)Native.loadLibrary("voxiebox",Voxilib.class);
	public interface Voxilib extends Library
	{
		public int    voxi_breath      (voxi_inputs_t ins);
		public void   voxi_doscreencap ();
		public void   voxi_drawbox     (voxi_frame_t vf, float x0, float y0, float z0, float x1, float y1, float z1, int fillmode, int col);
		public void   voxi_drawcube    (voxi_frame_t vf, point3d p, point3d r, point3d d, point3d f, int fillmode, int col);
		public float  voxi_drawheimap  (voxi_frame_t vf, tiletype pic, int usecomp, int colorkey, int heimin, float scx, float scy, float scz, float posx, float posy, float posz, int flags);
		public void   voxi_drawlin     (voxi_frame_t vf, float x0, float y0, float z0, float x1, float y1, float z1, int col);
		public void   voxi_drawpol     (voxi_frame_t vf, pol_t[] pt, int n, int col);
		public void   voxi_drawsph     (voxi_frame_t vf, float fx, float fy, float fz, float rad0, float rad1, int col);
		public void   voxi_drawspr     (voxi_frame_t vf, String st, point3d p, point3d r, point3d d, point3d f, int col);
		public void   voxi_drawvox     (voxi_frame_t vf, float fx, float fy, float fz, int col);
		public void   voxi_frame_end   ();
		public int    voxi_frame_start (voxi_frame_t vf);
		public int    voxi_keyread     ();
		public int    voxi_keystat     (int i);
		public double voxi_klock       ();
		public int    voxi_init        (voxi_wind_t vw);
		public int    voxi_loadini_int (voxi_wind_t vw);
		public void   voxi_playsound   (String st, int chan, int volperc0, int volperc1, float frqmul);
		public void   voxi_printalph   (voxi_frame_t vf, point3d p, point3d r, point3d d, int col, String st);
		public void   voxi_quitloop    ();
	 //public void   voxi_setaudmixcb (void usermixfunc(int[] sampbuf, int nsamps)); ???
		public void   voxi_setview     (voxi_frame_t vf, float x0, float y0, float z0, float x1, float y1, float z1);
		public void   voxi_uninit_int  ();
	}

	public static void main (String[] args) throws Exception
	{
		voxi_wind_t vw = new voxi_wind_t();
		voxi_frame_t vf = new voxi_frame_t();
		voxi_inputs_t ins = new voxi_inputs_t();
		pol_t pt_addr = new pol_t(); pol_t pt[] = (pol_t[])pt_addr.toArray(3);
		point3d pp = new point3d(), rr = new point3d(), dd = new point3d(), ff = new point3d();
		point3d pos = new point3d(0.0f,0.0f,0.0f), inc = new point3d(0.3f,0.2f,0.1f);
		double tim = 0.0, otim, dtim;
		int i = 0, mousx = 0, mousy = 0, mousz = 0;

		voxilib.voxi_loadini_int(vw); //get settings from KENTEST.INI. May override settings in vw structure here if desired.
		voxilib.voxi_init(vw); //Start video and audio.

		while (voxilib.voxi_breath(ins) == 0)
		{
			otim = tim; tim = voxilib.voxi_klock(); dtim = tim-otim;
			mousx += ins.dmousx; mousy += ins.dmousy; mousz += ins.dmousz;

			if (voxilib.voxi_keystat(0x1) != 0) { voxilib.voxi_quitloop(); }
			//int i = voxilib.voxi_keyread(); if ((i&255) == 27) voxilib.voxi_quitloop();

			if (voxilib.voxi_keystat(0x39) == 1) { voxilib.voxi_playsound(String.format("c:/windows/media/tada.wav"),0,100,100,1.0f); }

			i = (voxilib.voxi_keystat(0x1b)&1) - (voxilib.voxi_keystat(0x1a)&1);
			if (i != 0)
			{
					  if (voxilib.voxi_keystat(0x2a)+voxilib.voxi_keystat(0x36) != 0) vw.emuvang = Math.min(Math.max(vw.emuvang+(float)i*dtim*2.0,-Math.PI*.5),0.1268); //Shift+[,]
				else if (voxilib.voxi_keystat(0x1d)+voxilib.voxi_keystat(0x9d) != 0) vw.emudist = Math.max(vw.emudist-(float)i*dtim*2048.0,2000.0); //Ctrl+[,]
				else                                                                 vw.emuhang += (float)i*dtim*2.0; //[,]

				//if ((voxilib.voxi_keystat(0x2a) == 0) && (voxilib.voxi_keystat(0x36) == 0)) //no shifts down
				//   { vw.emuhang += (float)((float)i*dtim*2.0); } //[,]
				//else
				//{
				//   vw.emuvang += (float)((float)i*dtim*2.0); //Shift+[,]
				//   vw.emuvang = Math.min(Math.max(vw.emuvang,(float)Math.PI*-0.5f),0.1268f);
				//}

				voxilib.voxi_init(vw);
			}

			voxilib.voxi_frame_start(vf);
			voxilib.voxi_setview(vf,-vw.aspx,-vw.aspy,-vw.aspz,vw.aspx,vw.aspy,vw.aspz);

				//draw wireframe box
			//voxilib.voxi_drawbox(vf,-vw.aspx,-vw.aspy,-vw.aspz,vw.aspx,vw.aspy,vw.aspz,1,7);

				//draw various primitives
			for (float f=-1.0f; f<1.0f; f+=0.02f) {
				voxilib.voxi_drawvox(vf,f,0.0f,0.0f,7);
			}
			
			//voxilib.voxi_drawlin(vf,-vw.aspx,-vw.aspy,-vw.aspz,vw.aspx,vw.aspy,vw.aspz,7);
			//voxilib.voxi_drawsph(vf,pos.x,pos.y,pos.z,0.09f,0.10f,7);

			pt[0].set(-0.833f,-0.178f,-vw.aspz,1);
			pt[1].set(-0.298f,-0.178f,+   0.0f,2);
			pt[2].set(-0.536f,+0.129f,+vw.aspz,0);
			//voxilib.voxi_drawpol(vf,pt,3,7);

			rr.x = 0.2f; dd.x = 0.0f;                      pp.x = -0.7f;
			rr.y = 0.0f; dd.y = (float)Math.cos(tim)*0.4f; pp.y = +0.7f + dd.y*-.5f;
			rr.z = 0.0f; dd.z = (float)Math.sin(tim)*0.4f; pp.z = dd.z*-.5f;
			//voxilib.voxi_printalph(vf,pp,rr,dd,7,String.format("HI * " + (int)tim));

			rr.x = 0.39f; dd.x = 0.00f; ff.x = 0.00f; pp.x = (rr.x + dd.x + ff.x)*-0.5f + ((float)(mousx&511))/256.0f-1.0f;
			rr.y = 0.00f; dd.y = 0.39f; ff.y = 0.00f; pp.y = (rr.y + dd.y + ff.y)*-0.5f + ((float)(mousy&511))/256.0f-1.0f;
			rr.z = 0.00f; dd.z = 0.00f; ff.z = 0.39f; pp.z = (rr.z + dd.z + ff.z)*-0.5f;
			//voxilib.voxi_drawcube(vf,pp,rr,dd,ff,1,7);

				//make pos bounce around
			pos.x += inc.x*(float)dtim; if (Math.abs(pos.x) > vw.aspx-0.1) { inc.x *= -1.0; }
			pos.y += inc.y*(float)dtim; if (Math.abs(pos.y) > vw.aspy-0.1) { inc.y *= -1.0; }
			pos.z += inc.z*(float)dtim; if (Math.abs(pos.z) > vw.aspz-0.1) { inc.z *= -1.0; }

			voxilib.voxi_frame_end();
		}
		voxilib.voxi_uninit_int();
	}
}
